package com.itlzh.mall.user.serviceTest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * 切面类
 */
@Component
@Aspect
public class Assistant {
    /**
     * 切点表达式，serviceImpl类中的所有方法
     */
    @Pointcut(value = "execution(* com.itlzh.mall.user.serviceTest.impl.UserServiceImpl.*(..))")
    public void myPointcut(){}


    @Pointcut(value = "execution(* com.itlzh.mall.user.serviceTest.impl.UserServiceImpl.find(..))")
    public void findPointcut(){}

    @Pointcut(value = "execution(* com.itlzh.mall.user.serviceTest.impl.UserServiceImpl.delete(..))")
    public void deletePointcut(){}

    /**
     * 前置通知
     */
    @Before(value = "myPointcut()")
    public static void authentication(){
        System.out.println("身份审核通过");
    }

    /**
     * 后置通知
     * @param jp：连接点对象，用于提供连接点的元数据，如方法名、参数、返回值、类名、方法参数等
     */
    @After(value = "!findPointcut()")
    public static void doLog(JoinPoint jp){
        //获取连接点方法名
        String type=jp.getSignature().getName();
        System.out.println("记录"+type+"日志");
    }

    /**
     * 返回成功通知
     * @param jp 连接点参数
     * @param result 返回值回调结果
     */
    @AfterReturning(value = "!findPointcut() || deletePointcut()",returning = "result")
    public static void success(JoinPoint jp,boolean result){
        // 获取方法参数
        Object[] args = jp.getArgs();
        // 获取目标方法
        String type = jp.getSignature().getName();
        if(result){
            System.out.println(type + Arrays.toString(args) + "成功" );
        }else {
            System.out.println(type + Arrays.toString(args) + "失败" );
        }
    }

    /**
     * 异常通知
     * @param jp 连接点参数
     * @param e 异常回调
     */
    @AfterThrowing(value = "deletePointcut()",throwing = "e")
    public static void exception(JoinPoint jp,Throwable e){
        // 获取方法参数
        Object[] args = jp.getArgs();
        // 获取目标方法
        String type = jp.getSignature().getName();
        System.out.println("参数:" + Arrays.toString(args));
        System.out.println("异常:" + e.getMessage());
    }
    /**
     * 环绕通知
     * @param jp 连接点参数
     */
    @Around(value = "myPointcut()")
    public static void around(ProceedingJoinPoint jp){
        // 获取方法参数
        Object[] args = jp.getArgs();
        // 获取目标方法
        String type = jp.getSignature().getName();
        try{
            System.out.println("身份审核通过");
            Object result = jp.proceed();//调用目标方法
            if((Boolean) result){
                System.out.println(type + Arrays.toString(args) + "成功" );
            }else {
                System.out.println(type + Arrays.toString(args) + "失败" );
            }
        }catch (Throwable e){
            System.out.println("参数:" + Arrays.toString(args));
            System.out.println("异常:" + e.getMessage());
        }finally {
            System.out.println("记录" + type + "日志");
        }
    }

}

